package zf.media.audio
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	
	/**
	 * 一次声音播放结束 
	 * @eventType flash.events.Event.SOUND_COMPLETE
	 */
	[Event(name="soundComplete", type="flash.events.Event")]
	/**
	 * 循环声音播放结束 
	 * @eventType flash.events.Event.COMPLETE
	 */
	[Event(name="complete", type="flash.events.Event")]

	/**
	 * 声音单元，声音的基本控制。用于控制声音的音量，播放，停止，暂停 
	 * @author 张峰
	 * 
	 */
	public class SoundUnit extends EventDispatcher
	{
		private var _ID:String;
		private var _soundChannel:SoundChannel;
		private var _sound:Sound;
		private var _isPlay:Boolean=false;
		private var point:Number=0;
		private var _volume:Number=1;
		private var _pan:Number=0;
		private var _loop:int=1;
		private var _autoRemove:Boolean=true;
		public static const INFINITI:int=-1000;
		public function SoundUnit(id:String=null,snd:Sound=null)
		{
			_ID=id;
			_sound=snd;
		}

		/**
		 * 是否可以自动删除 
		 * @return 
		 * 
		 */
		public function get autoRemove():Boolean
		{
			return _autoRemove;
		}

		public function set autoRemove(value:Boolean):void
		{
			_autoRemove = value;
		}

		/**
		 * 平移 
		 * @return 
		 * 
		 */
		public function get pan():Number
		{
			return _pan;
		}

		public function set pan(value:Number):void
		{
			_pan = value;
			if(_soundChannel)
			{
				_soundChannel.soundTransform.pan=_pan;
			}
		}

		/**
		 * 循环次数，1,0均不循环，为 SoundUnit.INFINITI时无限循环
		 * @return 
		 * 
		 */
		public function get loop():int
		{
			return _loop;
		}

		public function set loop(value:int):void
		{
			_loop = value;
		}

		/**
		 * 音量 
		 * @return 
		 * 
		 */
		public function get volume():Number
		{
			return _volume;
		}

		public function set volume(value:Number):void
		{
			_volume = value;
			if(_soundChannel)
			{
				//_soundChannel.soundTransform.volume=_volume;
				_soundChannel.soundTransform=new SoundTransform(_volume,_soundChannel.soundTransform.pan);
			}
		}

		/**
		 * 是否播放 
		 * @return 
		 * 
		 */
		public function get isPlay():Boolean
		{
			return _isPlay;
		}

		/**
		 * 声音 
		 * @return 
		 * 
		 */
		public function get sound():Sound
		{
			return _sound;
		}

		public function set sound(value:Sound):void
		{
			_sound = value;
			
		}

		public function get soundChannel():SoundChannel
		{
			return _soundChannel;
		}

		/**
		 * 声音ID 
		 * @return 
		 * 
		 */
		public function get ID():String
		{
			return _ID;
		}

		public function set ID(value:String):void
		{
			_ID = value;
		}
		
		/**
		 * 播放 
		 * @param startTime 开始时间（毫秒）
		 * @param soundTransform 声道
		 * 
		 */
		public function play(startTime:Number=0,soundTransform:SoundTransform=null):void
		{
			if(_isPlay)
			{
				stopChannel();
			}
			if(soundTransform==null)
			{
				soundTransform=new SoundTransform(_volume,_pan);
			}
			_soundChannel=_sound.play(startTime,0,soundTransform);
			_isPlay=true;
			resetChannel();
		}
		/**
		 * 播放 暂停
		 * 
		 */
		public function playPause():void
		{
			if(_isPlay)
			{
				pause();
			}else
			{
				play(point);
			}
		}
		/**
		 * 暂停 
		 * 
		 */
		public function pause():void
		{
			point=_soundChannel.position;
			stopChannel();
		}
		/**
		 * 停止 
		 * 
		 */
		public function stop():void
		{
			stopChannel();
			try
			{
				_sound.close();	
			}catch(e:Error)
			{
				
			}
		}
		/**
		 * 清除声音 
		 * 
		 */
		public function dispose():void
		{
			stop();
			_soundChannel=null;
			_sound=null;
		}
		private function stopChannel():void
		{
			_soundChannel.stop();
			_isPlay=false;
			removeEvent();
		}
		private function resetChannel():void
		{	
			removeEvent();
			_soundChannel.addEventListener(Event.SOUND_COMPLETE,onSoundCompleteHandler);
		}
		private function removeEvent():void
		{
			if(_soundChannel.hasEventListener(Event.SOUND_COMPLETE))
			{
				_soundChannel.removeEventListener(Event.SOUND_COMPLETE,onSoundCompleteHandler);
			}
		}
		
		private function onSoundCompleteHandler(e:Event):void
		{
			_isPlay=false;
			point=0;
			this.dispatchEvent(new Event(Event.SOUND_COMPLETE));
			if(_loop==INFINITI)
			{
				play();
				return;
			}
			_loop--;
			if(_loop>0)
			{
				play();
			}else
			{
				this.dispatchEvent(new Event(Event.COMPLETE));
			}
			
		}
		override public function toString():String
		{
			return "SoundUnit "+_ID;
		}
	}
}